import sys
import os
sys.path.append(os.path.dirname(__file__))

from flask import Flask, request, jsonify, render_template
import logging
from core.git_manager import SecureGitManager
from core.build_pipeline import BuildPipeline

app = Flask(__name__)
# 禁用 Flask 的文件监听重载功能，避免 node_modules 中的文件更改触发重载
app.run_options = {'use_reloader': False}

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 默认仓库存储路径和构建输出路径
# 优先使用环境变量定义的路径，否则使用默认路径
DEFAULT_REPOS_PATH = os.environ.get('REPOS_PATH', os.path.join(os.path.dirname(__file__), "repos"))
DEFAULT_DIST_PATH = os.environ.get('DIST_PATH', os.path.join(os.path.dirname(__file__), "dist"))

# 确保默认目录存在
os.makedirs(DEFAULT_REPOS_PATH, exist_ok=True)
os.makedirs(DEFAULT_DIST_PATH, exist_ok=True)

# 存储正在进行的构建流水线
active_pipelines = {}

class BuildLogger:
    """构建过程日志记录器"""
    def __init__(self):
        self.logs = []
    
    def log(self, message):
        """记录日志信息"""
        log_entry = f"[{self._get_timestamp()}] {message}"
        self.logs.append(log_entry)
        logger.info(log_entry)
        print(log_entry)
    
    def _get_timestamp(self):
        """获取当前时间戳"""
        from datetime import datetime
        return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    
    def get_logs(self):
        """获取所有日志"""
        return self.logs

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/api/branches', methods=['POST'])
def get_branches():
    """获取远程仓库分支列表的API端点"""
    data = request.get_json()
    
    repo_url = data.get('repo_url', 'http://192.168.1.153:3000/tongyu.frontend/Asst-Manager.git')
    token = data.get('token', '32821a75cfbe7fdc896cb08818944934d6a5e296')
    
    try:
        git_manager = SecureGitManager()
        success, result = git_manager.get_remote_branches(repo_url, token)
        
        if success:
            return jsonify({
                'success': True,
                'branches': result
            })
        else:
            return jsonify({
                'success': False,
                'message': f'获取分支列表失败: {result}'
            }), 500
    except Exception as e:
        return jsonify({
            'success': False,
            'message': f'发生错误: {str(e)}'
        }), 500

@app.route('/api/clone', methods=['POST'])
def clone_repo():
    """克隆Git仓库的API端点"""
    data = request.get_json()
    
    repo_url = data.get('repo_url', 'http://192.168.1.153:3000/tongyu.frontend/Asst-Manager.git')
    token = data.get('token', '32821a75cfbe7fdc896cb08818944934d6a5e296')
    branch = data.get('branch', 'main')
    build_after_clone = data.get('build_after_clone', False)
    target_subpath = data.get('target_subpath', '')  # 新增的目标子路径参数
    
    # 创建日志记录器
    build_logger = BuildLogger()
    build_logger.log("开始克隆仓库操作")
    build_logger.log(f"仓库URL: {repo_url}")
    build_logger.log(f"分支: {branch}")
    
    try:
        # 从仓库URL提取仓库名
        repo_name = repo_url.rstrip('/').split('/')[-1].replace('.git', '')
        # 设置固定的本地路径
        local_path = os.path.join(DEFAULT_REPOS_PATH, repo_name)
        
        # 设置构建输出路径
        if target_subpath:
            target_path = os.path.join(DEFAULT_DIST_PATH, target_subpath)
            build_logger.log(f"使用自定义构建路径: {target_path}")
        else:
            target_path = os.path.join(DEFAULT_DIST_PATH, repo_name)
            build_logger.log(f"使用默认构建路径: {target_path}")
        
        # 如果本地路径已存在，先删除
        if os.path.exists(local_path):
            build_logger.log(f"删除已存在的本地路径: {local_path}")
            import shutil
            shutil.rmtree(local_path)
        
        git_manager = SecureGitManager(local_path)
        build_logger.log("开始克隆仓库...")
        success = git_manager.clone_with_token(repo_url, local_path, token, branch)
        
        if success:
            message = '仓库克隆成功'
            build_logger.log(message)
            local_path_abs = os.path.abspath(local_path)
            
            # 如果需要构建项目
            if build_after_clone:
                build_logger.log("初始化构建流水线...")
                # 创建新的构建流水线
                pipeline = BuildPipeline(local_path, target_path)
                # 生成一个唯一的流水线ID
                import uuid
                pipeline_id = str(uuid.uuid4())
                active_pipelines[pipeline_id] = pipeline
                
                # 返回流水线ID和第一个阶段信息
                next_stage = pipeline.get_next_stage()
                return jsonify({
                    'success': True,
                    'message': message,
                    'local_path': local_path_abs,
                    'logs': build_logger.get_logs(),
                    'pipeline_id': pipeline_id,
                    'next_stage': next_stage.name if next_stage else None,
                    'stage_count': len(pipeline.stages)
                })
            
            return jsonify({
                'success': True,
                'message': message,
                'local_path': local_path_abs,
                'logs': build_logger.get_logs()
            })
        else:
            error_message = '仓库克隆失败'
            build_logger.log(error_message)
            return jsonify({
                'success': False,
                'message': error_message,
                'logs': build_logger.get_logs()
            }), 500
    except Exception as e:
        error_message = f'发生错误: {str(e)}'
        build_logger.log(f"严重错误: {error_message}")
        return jsonify({
            'success': False,
            'message': error_message,
            'logs': build_logger.get_logs()
        }), 500

@app.route('/api/pull', methods=['POST'])
def pull_repo():
    """更新Git仓库的API端点"""
    data = request.get_json()
    
    token = data.get('token', '32821a75cfbe7fdc896cb08818944934d6a5e296')
    build_after_pull = data.get('build_after_pull', False)
    target_subpath = data.get('target_subpath', '')  # 新增的目标子路径参数
    
    # 创建日志记录器
    build_logger = BuildLogger()
    build_logger.log("开始更新仓库操作")
    
    # 从仓库路径推断项目名（使用repos目录下的第一个目录）
    repo_dirs = [d for d in os.listdir(DEFAULT_REPOS_PATH) 
                 if os.path.isdir(os.path.join(DEFAULT_REPOS_PATH, d))]
    
    if not repo_dirs:
        error_message = 'repos目录中没有找到仓库'
        build_logger.log(error_message)
        return jsonify({
            'success': False,
            'message': error_message,
            'logs': build_logger.get_logs()
        }), 400
    
    # 使用第一个仓库作为目标
    project_name = repo_dirs[0]
    local_path = os.path.join(DEFAULT_REPOS_PATH, project_name)
    
    # 设置构建输出路径
    if target_subpath:
        target_path = os.path.join(DEFAULT_DIST_PATH, target_subpath)
        build_logger.log(f"使用自定义构建路径: {target_path}")
    else:
        target_path = os.path.join(DEFAULT_DIST_PATH, project_name)
        build_logger.log(f"使用默认构建路径: {target_path}")
    
    build_logger.log(f"仓库路径: {local_path}")
    
    if not os.path.exists(local_path):
        error_message = '指定的本地路径不存在'
        build_logger.log(error_message)
        return jsonify({
            'success': False,
            'message': error_message,
            'logs': build_logger.get_logs()
        }), 400
    
    try:
        git_manager = SecureGitManager(local_path)
        build_logger.log("开始拉取仓库更新...")
        success = git_manager.pull_with_token(token)
        
        if success:
            message = '仓库更新成功'
            build_logger.log(message)
            
            # 如果需要构建项目
            if build_after_pull:
                build_logger.log("初始化构建流水线...")
                # 创建新的构建流水线
                pipeline = BuildPipeline(local_path, target_path)
                # 生成一个唯一的流水线ID
                import uuid
                pipeline_id = str(uuid.uuid4())
                active_pipelines[pipeline_id] = pipeline
                
                # 返回流水线ID和第一个阶段信息
                next_stage = pipeline.get_next_stage()
                return jsonify({
                    'success': True,
                    'message': message,
                    'logs': build_logger.get_logs(),
                    'pipeline_id': pipeline_id,
                    'next_stage': next_stage.name if next_stage else None,
                    'stage_count': len(pipeline.stages)
                })
            
            return jsonify({
                'success': True,
                'message': message,
                'logs': build_logger.get_logs()
            })
        else:
            error_message = '仓库更新失败'
            build_logger.log(error_message)
            return jsonify({
                'success': False,
                'message': error_message,
                'logs': build_logger.get_logs()
            }), 500
    except Exception as e:
        error_message = f'发生错误: {str(e)}'
        build_logger.log(f"严重错误: {error_message}")
        return jsonify({
            'success': False,
            'message': error_message,
            'logs': build_logger.get_logs()
        }), 500

@app.route('/api/build/init', methods=['POST'])
def init_build():
    """初始化构建项目的API端点"""
    data = request.get_json()
    target_subpath = data.get('target_subpath', '')  # 新增的目标子路径参数
    
    # 创建日志记录器
    build_logger = BuildLogger()
    build_logger.log("开始初始化构建项目操作")
    
    # 从仓库路径推断项目名（使用repos目录下的第一个目录）
    repo_dirs = [d for d in os.listdir(DEFAULT_REPOS_PATH) 
                 if os.path.isdir(os.path.join(DEFAULT_REPOS_PATH, d))]
    
    if not repo_dirs:
        error_message = 'repos目录中没有找到仓库'
        build_logger.log(error_message)
        return jsonify({
            'success': False,
            'message': error_message,
            'logs': build_logger.get_logs()
        }), 400
    
    # 使用第一个仓库作为目标
    project_name = repo_dirs[0]
    project_path = os.path.join(DEFAULT_REPOS_PATH, project_name)
    
    # 设置构建输出路径
    if target_subpath:
        target_path = os.path.join(DEFAULT_DIST_PATH, target_subpath)
        build_logger.log(f"使用自定义构建路径: {target_path}")
    else:
        target_path = os.path.join(DEFAULT_DIST_PATH, project_name)
        build_logger.log(f"使用默认构建路径: {target_path}")
    
    build_logger.log(f"项目路径: {project_path}")
    
    try:
        # 创建新的构建流水线
        pipeline = BuildPipeline(project_path, target_path)
        # 生成一个唯一的流水线ID
        import uuid
        pipeline_id = str(uuid.uuid4())
        active_pipelines[pipeline_id] = pipeline
        
        # 返回流水线ID和第一个阶段信息
        next_stage = pipeline.get_next_stage()
        return jsonify({
            'success': True,
            'message': '构建流水线初始化成功',
            'logs': build_logger.get_logs(),
            'pipeline_id': pipeline_id,
            'next_stage': next_stage.name if next_stage else None,
            'stage_count': len(pipeline.stages)
        })
    except Exception as e:
        error_message = f'发生错误: {str(e)}'
        build_logger.log(f"严重错误: {error_message}")
        return jsonify({
            'success': False,
            'message': error_message,
            'logs': build_logger.get_logs()
        }), 500

@app.route('/api/build/execute_stage', methods=['POST'])
def execute_build_stage():
    """执行构建阶段的API端点"""
    data = request.get_json()
    pipeline_id = data.get('pipeline_id')
    
    if not pipeline_id:
        return jsonify({
            'success': False,
            'message': '缺少流水线ID'
        }), 400
    
    if pipeline_id not in active_pipelines:
        return jsonify({
            'success': False,
            'message': '无效的流水线ID或流水线已结束'
        }), 400
    
    try:
        pipeline = active_pipelines[pipeline_id]
        stage_info, success, message, logs = pipeline.execute_next_stage()
        
        # 如果构建已完成，从活动流水线中移除
        if pipeline.is_completed() or not success:
            del active_pipelines[pipeline_id]
        
        return jsonify({
            'success': True,
            'stage_info': stage_info,
            'stage_success': success,
            'message': message,
            'logs': logs,
            'pipeline_completed': pipeline.is_completed() or not success,
            'pipeline_id': pipeline_id if not (pipeline.is_completed() or not success) else None
        })
    except Exception as e:
        error_message = f'发生错误: {str(e)}'
        logger.error(error_message)
        # 发生错误时移除流水线
        if pipeline_id in active_pipelines:
            del active_pipelines[pipeline_id]
        return jsonify({
            'success': False,
            'message': error_message
        }), 500

@app.route('/api/build/status', methods=['POST'])
def build_status():
    """获取构建状态的API端点"""
    data = request.get_json()
    pipeline_id = data.get('pipeline_id')
    
    if not pipeline_id:
        return jsonify({
            'success': False,
            'message': '缺少流水线ID'
        }), 400
    
    if pipeline_id not in active_pipelines:
        return jsonify({
            'success': False,
            'message': '无效的流水线ID或流水线已结束'
        }), 400
    
    try:
        pipeline = active_pipelines[pipeline_id]
        return jsonify({
            'success': True,
            'stage_status': pipeline.get_stage_status(),
            'current_stage_index': pipeline.current_stage_index
        })
    except Exception as e:
        error_message = f'发生错误: {str(e)}'
        logger.error(error_message)
        return jsonify({
            'success': False,
            'message': error_message
        }), 500

@app.route('/api/info')
def git_server_info():
    """获取Git服务器信息"""
    info = """
    获取访问令牌的常见方法：

    🏢 GitLab (如 http://192.168.1.153:3000):
       1. 登录后点击右上角头像
       2. 选择 "Edit profile" 或 "设置"
       3. 左侧菜单选择 "Access Tokens"
       4. 点击 "New personal access token"
       5. 设置名称和权限，然后创建

    🐙 GitHub:
       1. Settings → Developer settings → Personal access tokens
       2. 选择 "Tokens (classic)" 或 "Fine-grained tokens"
       3. 点击 "Generate new token"

    🌐 Gitea:
       1. Settings → Applications
       2. 在 "Personal Access Tokens" 部分操作

    🔐 令牌权限建议：
       - read_repository: 只读权限（拉取代码）
       - write_repository: 读写权限（推送代码）
    """
    return jsonify({
        'success': True,
        'info': info
    })

if __name__ == '__main__':
    # 禁用重载器以避免 node_modules 中的文件更改导致的重载问题
    app.run(debug=True, host='0.0.0.0', port=5000, use_reloader=False)